Skip to content

feat(rpc): implement getBlock#1221

Open
ajw221 wants to merge 62 commits intomainfrom
adamw/implement-getBlock-in-rpc
Open

feat(rpc): implement getBlock#1221
ajw221 wants to merge 62 commits intomainfrom
adamw/implement-getBlock-in-rpc

Conversation

@ajw221
Copy link
Contributor

@ajw221 ajw221 commented Feb 9, 2026

Intent

  • Implement getBlock RPC method

Implementation

Notable Validator Changes

  • Added helper methods to sig.core.transaction.Message for RPC encoding
  • Added missing cost_units field to sig.ledger.transaction_status.TransactionStatusMeta
  • Added pre balance and cost units tracking to ProcessedTransaction
  • Created TransactionStatusMetaBuilder helper type for writing transactions to Ledger
  • Created spl_token.zig and cost_model.zig for populating costUnits and computeUnitsConsumed fields
  • Updated Committer.commitTransactions to write transactions to Ledger
  • Updated distributeTransactionFees to write rewards to Ledger
  • Updated updateClock and updateSysvarsForNewSlot to return Clock for block_time writing to Ledger
  • Updated processNextInstruction to only invoke non-precompile programs
  • Updated InstructionTrace entries with a depth greater than 1 to now be cleaned up by TransactionContext

RPC Changes

  • Created parse_instruction module for handling transaction instruction parsing
  • Created AccountKeys, LoadedMessage, and ReservedAccountKeys types in parse_instruction to better match testnet functionality
  • Added new rpc hook context type for getBlock and any future Ledger-related methods

Ramifications

  • Current implementation is a bit verbose and will definitely be refactored in the near future, but will just be making note of the areas that should be cleaned up
    • AccountKeys, LoadedMessage, and ReservedAccountKeys should be removed in favor of custom handling in encoding functions and utilizing sig.core.ReservedAccounts instead, but should be done carefully to ensure no loss of functionality.
    • parse_instruction module can be split up into modules instead all functions living in parse_instruction/lib.zig, while additionally creating concrete type definitions for each inline JSON object being constructed for each type
    • GetBlock.Response types and getBlock helper functions should be moved into their own parse_transaction or ledger_codec module to separate RPC method logic from encoding/serialization

Tests

  • Added various unit tests on added functionality for better code coverage and serialization

- Created TransactionStatusMetaBuilder type for writing transaction metadata to the ledger
- Created BlockReward type for block-level reward tracking
- Added unix_timestamp (block_time) and rewards fields to SlotState
- Updated unit tests to cover new fields and types
- Write TransactionStatusMeta for RPC getBlock/getTransaction
- Store block rewards and unix timestamp when rooting slots
- Add SPL token parsing and transaction cost model
@ajw221 ajw221 self-assigned this Feb 9, 2026
@github-project-automation github-project-automation bot moved this to 🏗 In progress in Sig Feb 9, 2026
@ajw221 ajw221 changed the base branch from main to adamw/implement-getSlot-in-rpc February 9, 2026 17:01
…lumbing

- Thread slot_block_time through clock sysvar updates so replay/rooting can access unix timestamps directly
- Adjust getBlock handling to use stored block_time and tighten version checks
- Add ExecutedTransaction.total_cost() and use it for CU accounting
- Relax u8 index panics in transaction status inner-instruction/token balance builders
- Minor cleanups/refactors across replay, cost model, and SPL token parsing
@prestonsn prestonsn force-pushed the adamw/implement-getSlot-in-rpc branch from 40fae04 to 72d8727 Compare February 9, 2026 17:58
Specify std.atomic.Value(i64) type on slot_block_time declarations
to fix type inference.
@ajw221 ajw221 force-pushed the adamw/implement-getBlock-in-rpc branch from 07d17c1 to 03340ef Compare February 9, 2026 20:09
@codecov
Copy link

codecov bot commented Feb 9, 2026

Codecov Report

❌ Patch coverage is 94.57410% with 93 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/replay/Committer.zig 66.95% 38 Missing ⚠️
src/replay/freeze.zig 57.44% 20 Missing ⚠️
src/ledger/transaction_status.zig 94.04% 14 Missing ⚠️
src/rpc/methods.zig 96.07% 10 Missing ⚠️
src/runtime/spl_token.zig 99.18% 5 Missing ⚠️
src/runtime/program/system/lib.zig 85.71% 4 Missing ⚠️
src/replay/rewards/lib.zig 75.00% 2 Missing ⚠️
Files with missing lines Coverage Δ
src/core/ReservedAccounts.zig 100.00% <ø> (ø)
src/core/hash.zig 97.97% <100.00%> (+0.02%) ⬆️
src/core/transaction.zig 93.50% <100.00%> (+0.01%) ⬆️
src/ledger/Ledger.zig 90.24% <100.00%> (+2.00%) ⬆️
src/ledger/Reader.zig 89.67% <ø> (-0.01%) ⬇️
src/ledger/ResultWriter.zig 95.76% <100.00%> (+2.04%) ⬆️
src/ledger/tests.zig 88.71% <ø> (ø)
src/replay/execution.zig 91.93% <100.00%> (+0.03%) ⬆️
src/replay/rewards/calculation.zig 88.67% <100.00%> (+0.08%) ⬆️
src/replay/rewards/distribution.zig 95.43% <100.00%> (+0.58%) ⬆️
... and 24 more

... and 3 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

…acks

- Add confirmed commitment path matching Agave's two-phase lookup flow
- Fall back to blockstore for block_time, block_height, and rewards when
  SlotTracker has pruned the slot
- Fix Reward.fromLedgerReward to dupe pubkey string instead of parsing
Use unix_timestamp.load(.monotonic) for live slot data accuracy.
@prestonsn prestonsn force-pushed the adamw/implement-getSlot-in-rpc branch 2 times, most recently from e7172e5 to 0568f9e Compare February 12, 2026 22:08
@ajw221 ajw221 force-pushed the adamw/implement-getBlock-in-rpc branch from e00bb37 to 4e9d457 Compare February 13, 2026 18:31
@ajw221 ajw221 force-pushed the adamw/implement-getSlot-in-rpc branch from 7d84370 to 8279fe0 Compare February 14, 2026 03:24
@ajw221 ajw221 force-pushed the adamw/implement-getBlock-in-rpc branch from 11ab9b5 to 894fae1 Compare February 14, 2026 03:26
Base automatically changed from adamw/implement-getSlot-in-rpc to main February 17, 2026 16:53
- Add AccountKeys and ReservedAccountKeys for key segment iteration
- Create parse_instruction module with parsers for known programs
- Refactor transaction encoding with encodeWithOptions helper
- Rename types to use Ui prefix for RPC wire format consistency
- Fix transaction version handling in encodeTransactionWithMeta
- Update transaction version to use a labeled block
- Rename SPL_ASSOCIATED_TOKEN_ACCOUNT_ID to SPL_ASSOCIATED_TOKEN_ACC_ID
- Remove commented-out ParsedInstruction union code
- Add doc comment for ParsedInstruction struct
- Apply consistent formatting to pubkeyToValue calls
@ajw221 ajw221 force-pushed the adamw/implement-getBlock-in-rpc branch from 894fae1 to 481b662 Compare February 17, 2026 17:25
…on metadata

- Replace string pubkeys/hashes with typed Pubkey/Hash/Signature throughout
- Add FallbackAccountReader to check both writes and account store for mints
- Add custom jsonStringify methods for proper Agave-compatible serialization
- Remove unnecessary manual memory freeing for typed fields
- Fix inner instructions to use UiInstruction union type
- Support all transaction encoding formats (binary/base58/base64/json)
@ajw221 ajw221 force-pushed the adamw/implement-getBlock-in-rpc branch from 2a3553d to 665392e Compare February 17, 2026 21:08
- Change UiInstruction.parsed to store a pointer instead of value
- Add allocParsed helper to heap-allocate parsed instructions
- Reduces union size by avoiding large inline struct
@ajw221 ajw221 force-pushed the adamw/implement-getBlock-in-rpc branch from 204c63f to 90fdd5e Compare February 25, 2026 22:17
@github-project-automation github-project-automation bot moved this from 🏗 In progress to 👀 In review in Sig Feb 26, 2026
- Resolve loaded writable/readonly keys from address lookups instead of
  using empty placeholders
- Fix errdefer for owned_loaded_addresses in TransactionStatusMetaBuilder
  to free individual fields rather than the struct
- Add missing errdefer for data allocations in FallbackAccountReader
- Fix FallbackAccountReader.get parameter order (allocator, pubkey)
- Remove stored allocator from StubAccount, pass explicitly on deinit
@ajw221 ajw221 force-pushed the adamw/implement-getBlock-in-rpc branch from 90fdd5e to 47b0463 Compare February 26, 2026 15:43
- Add getRewardsAndNumPartitions to collect vote, stake, and fee rewards per slot
- Thread reward_status and block_height through to distributeTransactionFees
- Track distributed stake rewards during partition distribution
- Store vote rewards in EpochRewardStatus for epoch boundary recording
- Deinit inner items of inner_instructions, pre/post_token_balances before freeing slices
- Change pre/post token balance cleanup from defer to errdefer in Committer since ownership transfers to TransactionStatusMeta
- Add exactFloat helpers to format f64 with decimal point (e.g. "3.0" instead of "3e0")
- Use number_string instead of float for uiAmount in parsed token balances
- Update test expectation to reflect correct "1.0" serialization
- Deinit inner items of inner_instructions, pre/post_token_balances before freeing slices
- Change pre/post token balance cleanup from defer to errdefer in Committer since ownership transfers to TransactionStatusMeta
@ajw221 ajw221 force-pushed the adamw/implement-getBlock-in-rpc branch from cdf0a23 to 1890b73 Compare February 26, 2026 22:17
… program

- Add errdefer for inner instruction to prevent leak on append failure
- Remove unnecessary dupe of log_messages, use meta field directly
- Use allocator.dupe with inline array literals in system program helpers
…256r1 cost model

- Change resolveTokenBalances return type to error{OutOfMemory}- Use appendAssumeCapacity since list is pre-allocated to exact size
- Add catch null at Committer call sites to preserve existing behavior
- Enable secp256r1 precompile signature cost calculation in cost_model
- Minor style cleanups in spl_token helpers
- Add ED25519_VERIFY_STRICT_COST constant alongside existing ED25519_VERIFY_COST
- Add remove_simple_vote_from_cost_model to features.zon
- Gate simple vote static cost on remove_simple_vote_from_cost_model feature
- Pass feature_set and slot to cost model functions for feature-gated behavior
- Use strict ed25519 verify cost (2400 CU) only when feature is active, non-strict (2280 CU) otherwise
- Delete duplicate ReservedAccountKeys in rpc/parse_instruction
- Add initAllActivated constructor to core ReservedAccounts
- Add errdefer to initForSlot for proper cleanup on update failure
- Change ACCOUNTS from slice to array type for use with .len
- Update LoadedMessage and transaction.Message to use PubkeyMap(void)
- Remove stale commented-out code in ParsedInstruction
- Remove LoadedMessage wrapper and its writable cache in favor of calling Message.isWritable with optional lookups
- Remove duplicate isMaybeWritable/isWritableIndex/demoteProgramId helpers from Message
- Simplify EncodedTransaction.binary to use anonymous struct (tuple)
- Remove unused buildPartiallyDecoded function from parse_instruction
- Reorder FinalizeStateParams fields for grouping clarity
- Improve CPI instruction data clone comment to explain use-after-free risk
- Move LedgerHookContext from methods.zig to rpc/hook_contexts/Ledger.zig
- Create rpc/hook_contexts/lib.zig module entry point
- Update cmd.zig import path to use new module location
- Move all associated tests to the new file
- Use colon-separated test name format (module.function: description)
- Use camelCase for enum variants in TokenInstructionTag and TokenAuthorityType
- Remove exhaustive enum sentinel values, rely on compiler exhaustiveness
- Inline TokenAuthorityType methods as switch expressions at call site
- Remove section separator comments, add agave reference links instead
- Alphabetize and inline import aliases in parse_instruction
- Add parsers for all 14 token extension types (transferFee,
  confidentialTransfer, defaultAccountState, memoTransfer, etc.)
- Add helper functions for reading OptionalNonZeroPubkey and COption<Pubkey>
- Parse sub-instruction tags, account keys, and data fields per agave spec
- Replace stub that returned DeserializationFailed for all extensions
- Rename allocator parameters to arena throughout Ledger and parse_instruction
- Remove errdefer/defer free calls that are redundant with arena allocation
- Convert tests to use ArenaAllocator instead of testing.allocator directly
- Fix arena.reset() calls to not discard return value
- Break long function call arguments across multiple lines
- Wrap info.put and parseSigners calls to stay within line limits
- Reformat extension dispatch calls in parseTokenInstruction
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: 👀 In review

Development

Successfully merging this pull request may close these issues.

4 participants